\section{Aspetti progettuali}\label{aspettiProgettuali}
In questa sezione si tenta di fornire una panoramica sui possibili guasti legati all'architettura scelta per la nostra applicazione.
\subsection{Scelta dell'architettura}
Come accennato nella sezione introduttiva, tutti gli sforzi progettuali sono stati catalizzati al fine di ottimizzare lo scambio di messaggi nelle procedure di coordinamento.
I punti cruciali di questa ottimizzazione sono l'adozione di un approccio ottimistico, e l'abilitazione dei singoli peer a calcolore lo stato del gioco e a risolvere in parte autonoma i guasti rilevati.
\'E stato possibile percorrere tali strade basandoci esclusivamente su un'analisi preventiva dei requisiti del sistema (e.g. ``\emph{tollerenza a guasti di tipo crash, canali di comunicazioni affidabili}'') e sulla natura del gioco scelto (UNO, il gioco di carte).
\\UNO, si basa su una logica di gioco a turno, fortemente sequenziale, e non prevede processi di gioco concorrenti.
Questa assunzione ci ha permesso di modellare l'architettura astratta del sistema mediante \emph{token ring}.
\\Il token ring ci consente di effettuare le invocazioni remote in maniera ordinata e naturalmente causale, grazie al quale è stato possibile realizzare politiche di \emph{``comunicazione affidabile''} con poco sforzo, garantendo l'invio e la ricezione ordinata di eventi legati da relazioni di causalità logica.

\subsection{Aggiornamento dello stato}\label{aggiornamentoDelloStato}
L'aggiornamento dello stato, come accennato nella sezione \ref{introduzione}, può essere prodotto solo contestualmente al verificarsi di un evento rilevante all'interno del sistema.
\\Come semplificazione, il nostro modello, prevede che gli eventi rilevanti vengano prodotti sempre dal processo leader dello stato corrente. Il leader infatti rappresenta il peer che possiede il turno di gioco, quindi la facoltà di giocare una carta e avanzare (cambiare lo stato del sistema).
L'evento, ovvero l'azione che si manifesta nella giocata del processo leader, è stata modellata come il \emph{token} dell'anello. Tale token viene propagato, attraverso tutto l'anello in direzione anti-gioco in modo tale che il candidato leader sia l'ultimo a ricevere la notifica riguardante la giocata del leader corrente.
Ogni peer, ad ogni richiesta di aggiornamento dello stato, contestualmente alla ricezione della giocata, calcolerà autonomamente il nuovo stato di gioco, e quindi anche la nuova leadership, in base alle informazioni contenute nel token. Il nuovo leader, essendo l'ultimo ad aver ricevuto lo stato ha la garanzia che tutti gli altri peer hanno una vista coerente sullo stato del gioco e quindi, può in qualsiasi momento fare la propria giocata.

\subsection{Gestione dei guasti}
Le specifiche di progetto impongono di rendere il sistema tollerante ad almeno 3 guasti di tipo crash. Il modello di token ring e le modalità di propagazione del token adottate (vedi \ref{aggiornamentoDelloStato}) ci hanno consentito di tollerare, mediante algoritmi di recovery iterativi, $n-1$ guasti.
\\L'idea è che l'unico guasto ritenuto importante è un crash del processo che detiene la leaderhip in quell'istante di gioco. Quindi, tutti i peer che attendono una giocata dal processo leader, controlleranno che quest'ultimo non abbia subito guasti, tramite una procedura di attesa (basata sul polling) scandita da un timeout. Nel caso di rilevamento di un guasto ogni peer, in maniera autonoma, calcolerà la nuova leadership e applicher\`a la procedura di attesa sul nuovo leader, ricorsivamente.
\\Pur non essendo previsti guasti ai canali di comunicazione, abbiamo modellato una tipologia di guasto molto vicina.
Lo scenario si costituisce in questo modo: il processo leader effettua la giocata e propaga il token in senso anti-gioco. Un peer intermedio, tra il leader corrente ed il candidato leader, riceve il token, ma prima di propagarlo al peer successivo ha un guasto. Il leader corrente non può sapere se il token si sta propagando regolarmente o meno.
\\L'idea che sta alla base della gestione di questa tipologia di guasti è la ripetizione, da parte del leader, del messaggio. Tale procedura viene temporizzata mendiante un timeout. Nelle successive iterazioni di propagazione, i peer caduti in quelle precedenti, verranno rimossi dalle liste dei peer che li precedono nell'anello. Nel caso peggiore, con $n$ iterazioni abbiamo la garanzia che il guasto venga tollerato con $\frac{n \cdot (n-1)}{2}$ invocazioni remote effettuate. Nel caso migliore $n$.
\\Molti altri casi particolari di guasti vengono risolti con la stessa politica ricorsiva di adattamento dello schema risolutivo. Si rimanda alla sezione \ref{aspettiImplementativi} per dettagli e approfondimenti.
